import java.io.File;
import java.io.IOException;
import java.util.Vector;

import metrics.NormalizedPRStatictic;
import metrics.PRStatistic;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;


public class RelevanceFeedback {
	
	private static final String RELEVANCY_LIST = "TIME" + File.separator
	+ "RelevancyLists.txt";
	
	private Vector<Query> queries;
	private Vector<String> mostRelevants;
	private Directory index;

	public RelevanceFeedback(Vector<Query> queries,
			Vector<String> mostRelevants, Directory index) {
		
		this.queries = queries;
		this.mostRelevants = mostRelevants;
		this.index = index;
	
	}

	public NormalizedPRStatictic getStatictics(double weightOld, double weightDoc) throws CorruptIndexException, IOException {

		RelevanceReference ref = new RelevanceReference(RELEVANCY_LIST);
		Vector<NormalizedPRStatictic> normalizedStatistics = new Vector<NormalizedPRStatictic>();
		
		int currentQuery = 0;
		
		for (Query q : queries) {
		
			int hitsPerPage = 300;
			IndexSearcher searcher = new IndexSearcher(index, true);
			TopScoreDocCollector collector = TopScoreDocCollector.create(
					hitsPerPage, true);
			searcher.search(q, collector);
			ScoreDoc[] hits = collector.topDocs().scoreDocs;

			System.out.println("Found " + hits.length + " hits.");

			int relevantDocs = ref.relevantCountForQuery(currentQuery);
			int hitcount = 0;
			PRStatistic statistic = new PRStatistic();

			for (int i = 0; i < hits.length && hitcount < relevantDocs; ++i) {
				int docId = hits[i].doc;
				Document d = searcher.doc(docId);
				
				if (ref.isRelevant(d.get("title"), currentQuery)) {
					hitcount++;
					//System.out.println((i + 1) + ". " + d.get("title")+ " :-)");
				} else {
					//System.out.println((i + 1) + ". " + d.get("title") + " :-(");
				}
				statistic.addEntry(hitcount/(float)relevantDocs, hitcount/(float)(i+1));
				//System.out.println("recall:" + hitcount/(float)relevantDocs + " precision:" + hitcount/(float)(i+1));
			}
			
			normalizedStatistics.add(statistic.getNormalizedVersion());
			
			
			searcher.close();
			currentQuery++;
			
		}
		
		//Compute the Average
		NormalizedPRStatictic summary = new NormalizedPRStatictic();
		for(int i =0; i<=NormalizedPRStatictic.NORMALIZAION_PRECISION; i++) {
			float sum = 0;
			for (NormalizedPRStatictic statictic : normalizedStatistics) {
				sum += statictic.getPrecisionOfEntry(i);
			}
			summary.addEntry((float)i/NormalizedPRStatictic.NORMALIZAION_PRECISION, sum/(float)normalizedStatistics.size());
		}
		
		return summary;
	}

}
